/*
 Автор: Швейкин Евгений Юрьевич


 Функциональное описание:     

*/
//--------------------------------------------------------------------------------------------------
`timescale 1ns / 10ps

//    ********************** НАЧАЛО МОДУЛЯ *********************************************************
module mod_version 
    #(
        parameter logic [7:0]                       ver_h_p = 0,
        parameter logic [7:0]                       ver_m_p = 0,
        parameter logic [7:0]                       ver_l_p = 0,
        parameter logic [31:0] [31:0]               text_p  = "1234567890abcdef1234567890abcdef" 
    
    )
    (   input logic             reset,
        input logic             clk,

        output logic [11:0]     date_yy,
        output logic [3:0]      date_mm,
        output logic [4:0]      date_dd,

        output logic [5:0]      time_hh,
        output logic [5:0]      time_mm,
        output logic [5:0]      time_ss,

        output logic [4:0]      ver_h,
        output logic [4:0]      ver_m,
        output logic [4:0]      ver_l,

        output logic [15:0]     build
    );
        
//    ********************* ПОДКЛЮЧЕНИЕ ВНЕШНИХ МОДУЛЕЙ ********************************************
    altsyncram
    #(
        .clock_enable_input_a   ("BYPASS"),
        .clock_enable_output_a  ("BYPASS"),
        .init_file              ("ver.mif"),
        .intended_device_family ("Stratix II GX"),
        .lpm_hint               ("ENABLE_RUNTIME_MOD=YES,INSTANCE_NAME=vvv"),
        .lpm_type               ("altsyncram"),
        .numwords_a             (32),
        .operation_mode         ("SINGLE_PORT"),
        .outdata_aclr_a         ("NONE"),
        .outdata_reg_a          ("CLOCK0"),
        .power_up_uninitialized ("FALSE"),
        .widthad_a              (5),
        .width_a                (32),
        .width_byteena_a        (1)
    )
    altsyncram_inst1
    (
        .wren_a     (wren),
        .clock0     (clk),
        .address_a  (addr),
        .data_a     (data_wr),
        .q_a        (data_rd)
        );
//  ********************* КОНСТАНТЫ ****************************************************************
        localparam logic [4:0]      text_size_p  = 5'd28;
//  ********************* ТИПЫ ДАННЫХ **************************************************************

//  ********************* ПЕРЕМЕННЫЕ ***************************************************************

    logic [4:0]         addr;
    logic [4:0]         addr_0;
    logic [4:0]         addr_1;
    logic [4:0]         txt_word_cnt;
    
    
    logic [31:0]        data_wr;
    logic [31:0]        data_rd;
    logic               wren;
    logic [31:0]        rez;
    
//  ********************* ASSIGN *******************************************************************

// ********************* ПРОЦЕССЫ ******************************************************************

    always_ff @(posedge clk)
    begin
        addr    <= addr + 5'h1;
        addr_0  <= addr;
        addr_1  <= addr_0;
    end
    
    always_ff @(posedge clk)
    begin
        wren            <= 1'b0;
        data_wr         <= 32'h0;
        txt_word_cnt    <= 5'h0;
        if (addr == 5'h1) begin
            wren    <= 1'b1;
            data_wr <= {8'h0, ver_h_p, ver_m_p, ver_l_p};
        end
        else if ((addr >= 5'h3) && (addr < text_size_p + 5'h3))begin
            wren        <= 1'b1;
            data_wr     <= text_p[text_size_p - txt_word_cnt - 1];
            txt_word_cnt<= txt_word_cnt + 5'd1;
        end
        else;
    end
    
    always_ff @(posedge clk)
    begin
        if (addr_1 == 5'h0) begin
            {rez[1:0], date_yy} <=  data_rd[31:28] * 10'd1000 + 
                                    data_rd[27:24] * 10'd100 + 
                                    data_rd[23:20] * 10'd10 + 
                                    data_rd[19:16];
                        
            {rez[3:0], date_mm} <=  data_rd[15:12] * 4'd10 + 
                                    data_rd[11:8];
                
            {rez[2:0], date_dd} <=  data_rd[7:4] * 4'd10 + 
                                    data_rd[3:0];
        end 
        else if (addr_1 == 5'h1) begin
            
            {rez[1:0], time_hh} <=  data_rd[23:20] * 4'd10 + 
                                    data_rd[19:16];
            
            {rez[1:0], time_mm} <=  data_rd[15:12] * 4'd10 + 
                                    data_rd[11:8];   
                            
            {rez[1:0], time_ss} <=  data_rd[7:4] * 4'd10 + 
                                    data_rd[3:0];
        end
        else if (addr_1 == 5'h2) begin
            ver_h   <= ver_h_p[4:0];
            ver_m   <= ver_m_p[4:0];
            ver_l   <= ver_l_p[4:0];
        end
        else if (addr_1 == 5'h3) begin
            build   <=  data_rd[15:12] * 10'd1000 + 
                        data_rd[11:8] * 10'd100 + 
                        data_rd[7:4] * 10'd10 + 
                        data_rd[3:0];
        end
        else;
    end
    
    
endmodule